;********************************************************************** ; * ; Filename: PIC RS232 Interface * ; Date: 22/03/08 * ; Version: 1.1 * ; * ; Written By: MSH * ; * ; Microcontroller: PIC16F84A * ; Clock Frequency: 8 MHz * ; * ;********************************************************************** ; ;====================================================================== ; Program Function: PIC controller serial interface utilizing the ; MAX232A chip. For transmitting 8 bit data from PC to ; 8 LEDs output on RB0 - RB7 ports. list p=16F84A ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_OFF & _XT_OSC ;======================================================================= ; Declarations: porta equ 0x05 ; portb equ 0x06 ; chartr equ 0x0C ; Data character received & xmitted. bitctr equ 0x0D ; Bit Counter. acount equ 0x0E ; Delay count a. bcount equ 0x0F ; Delay count b. comflag equ 0x10 ; Communications flags. cntra equ 0x11 ; Delay counter a. cntrb equ 0x12 ; Delay counter b. recreg equ 0x13 ; Received data character. xmtreg equ 0x14 ; Transmitted data character. post130 equ 0x15 ; mark30 equ 0x16 ; binstore equ 0x17 ; #define RA2_TX porta,2 ; Porta (2) is transmit. #define RA3_RX porta,3 ; Porta (3) is receive. org 0x00 goto start ;====================================================================== ; Subroutines: INIT clrf porta ; resets I/O ports. clrf portb ; bsf STATUS,5 ; selects bank 1. movlw b'01000' ; RA0-1: spare, RA2: RS232_Tx, movwf TRISA ; RA3: RS232_Rx, RA4: Spare. movlw b'00000000' ; RB0 - RB7: LEDs 1 to 8. movwf TRISB ; movlw b'00000111' ; TMR0 prescaled by 256 movwf OPTION_REG ; pull ups disabled. bcf STATUS,5 ; selects bank 0. movlw b'00000000' ; Disables all Interrupts. movwf INTCON ; movlw d'130' ; Places the decimal number '130' into the movwf post130 ; file register post130. movlw d'30' ; Places the decimal number '30' into the movwf mark30 ; file register mark30. clrf bitctr ; resets bitctr. clrf comflag ; resets comflag. clrf binstore ; resets binstore. bsf RA2_TX ; Set transmit to high. movlw b'11110000' ; movwf xmtreg ; return ; Returns from Subroutine. ;/////////////////////////////////////////////////////////////////////////////////// Serial_Rx asyrec bcf comflag,1 ; Clear start error flag. bcf comflag,0 ; Clear framing error flag. movlw d'09' ; 8 data bits + stop bit. movwf bitctr ; asyrec1 btfsc RA3_RX ; start bit (rec port low)? If yes, skip! goto asyrec1 ; no. go try again. call half ; wait 1/2 bit time btfss RA3_RX ; still start bit? If no, skip next. goto asyrec3 ; yes. go bsf comflag,1 ; no. set start error flag. goto asyrecx ; & go exit. asyrec3 call full ; yes. wait 1 bit time. decfsz bitctr,f ; update bit counter. If all bits done, skip goto asyrec4 ; not all done. go read bit. btfss RA3_RX ; all done. Stop bit present? If yes, skip. bsf comflag,0 ; no. set framing error flag. goto asyrecx ; & go exit. asyrec4 bsf STATUS,C ; set carry flag. btfss RA3_RX ; get data bit. Is it 1? If yes, skip. bcf STATUS,C ; no. clear carry flag. rrf recreg,f ; rotate carry to received character. goto asyrec3 ; go wait for next bit. asyrecx retlw 0 ; Exit. ;////////////////////////////////////////////////////////////////////////////////// Serial_Tx asyxmt bcf RA2_TX ; Start bit. call full ; Wait 1 bit time. movlw d'08' ; 8 bit character length. movwf bitctr ; to bit counter. asyxmt1 rrf xmtreg,f ; rotate bit out thru carry. btfsc STATUS,C ; carry = 0 ? IF YES, SKIP. goto asyxmt2 ; no. carry = 1. Go set pal. bcf RA2_TX ; data bit = 0. Clear pal. goto asyxmt3 ; & go. asyxmt2 bsf RA2_TX ; data bit = 1. Set pal. ; asyxmt3 call full ; Wait 1 bit time. decfsz bitctr,f ; all 8 bits sent? If yes, skip. goto asyxmt1 ; no, go do next bit. ; bsf RA2_TX ; all bits done. do stop bit (marking). call full ; waiting 1 bit time. retlw 0 ; Exit. ;/////////////////////////////////////////////////////////////////////////////////// data_to_led movfw recreg ; Take Recieved character out of "recreg" and movwf portb ; place into portb. call full ; Creates 1 bit delay. retlw 0 ; Returns from subroutine. ;//////////////////////////////////////////////////////////////////////////////////// half_sec clrf TMR0 ; clears TMR0 half_seca movfw mark30 ; takes the number out of mark30. subwf TMR0,w ; subtracts this number from the number ; in TMR0, leaving the result in the ; working register (and leaving TMR0 unchanged). btfss STATUS,Z ; tests the zero flag - skip if set i.e. if the ; result is zero it will skip the next instruction. goto half_seca ; loops to half_seca. decfsz post130,f ; goto half_seca ; loops to half_seca. movlw d'130' ; Places the decimal number '130' into the movwf post130 ; file register post130. retlw 0 ;LED_TEST ; movlw b'11111111' ; ; movwf portb ; ;loop1 call full ; ; call full ; ; decfsz post100 ; ; goto loop1 ; ; movlw d'100' ; Places the decimal number '100' into the ; movwf post100 ; file register post100. ; decfsz post50 ; ; goto loop1 ; ; movlw d'50' ; Places the decimal number '50' into the ; movwf post50 ; file register post50. ; movlw b'00000001' ; ; movwf portb ; ; retlw 0 ; vdly movf bcount,w ; bcount to counter b movwf cntrb ; vdly0 movf acount,w ; acount to counter a movwf cntra ; vdly1 decfsz cntra,f ; dec counter a, skip if zero. goto vdly1 ; not zero. dec it again. decfsz cntrb,f ; dec counter b, skip if zero goto vdly0 ; not zero. do loop again. retlw 0 ; exit. ;---------------------------------------------------------------------- half movlw d'6' ; wait 1/2 bit time (2400 bits per second) movwf bcount ; movlw d'21' ; movwf acount ; call vdly ; retlw 0 ; returns from subroutine. ;---------------------------------------------------------------------- full movlw d'6' ; wait 1 bit time (2400 bits per second) movwf bcount ; movlw d'44' ; movwf acount ; call vdly ; retlw 0 ; returns from subroutine. ;---------------------------------------------------------------------- ;==================================================================== ; Program Start: start call INIT ; ; call LED_TEST ; main call Serial_Rx ; btfsc comflag,1 ; goto main ; loops to com1. btfsc comflag,0 ; goto main ; loops to com0. call data_to_led ; call full ; bsf RA2_TX ; Set transmit to high. call Serial_Tx ; call half_sec ; half_sec time delay. clrf portb ; resets all LEDs. call half_sec ; half_sec time delay. goto main ; loops to main. END ; directive 'end of program' ;*************************************************************************** ; Module: vdly.txt ; Delay used for bit timing. ; Cycle Time: 1 microsec (4 MHz xtal). ; Delay Module: vdly.txt ; ; ;*************************************************************************** ;* Rate * Bit Time * For 1 Bit * For 1/2 Bit * ;* * (uSec) * bcount * acount * delay(us) * bcount * acount * delay * ;*************************************************************************** ;* 110 * 9090.9 * 13 * 231 * 9074 * 13 * 115 * 4550 * ;* 300 * 3333.3 * 13 * 81 * 3324 * 13 * 41 * 1654 * ;* 600 * 1666.7 * 12 * 44 * 1644 * 6 * 44 * 822 * ;* 1200 * 833.3 * 3 * 89 * 816 * 3 * 42 * 399 * ;* 2400 * 416.7 * 3 * 43 * 402 * 3 * 20 * 191 * ;* 4800 * 208.8 * 2 * 29 * 184 * 2 * 13 * 87 * ;* 9600 * 104.2 * 1 * 27 * 86 * 1 * 11 * 35 * ;*19200 * 52.1 * 1 * 9 * 32 * 1 * 1 * 8 * ;*************************************************************************** ; ; Variable Timing Delay. Delay parameters are: acount & bcount. ; delay approx = (3)*(cycletime)*(acount)*(bcount) ; +(5)*(cycletime)*(bcount) ; ; Total time from: call full ; to: next instruction (return location) ; is approximately = delay + (12)*(cycletime) ; ; Requires following workspace: acount count parameter a ; bcount count parameter b ; cntra counter a ; cntra counter b ; ; ; ;